<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
	<title>过滤集提升权重 | Elasticsearch: 权威指南 | Elastic</title>
    <!-- Give IE8 a fighting chance -->
    <!--[if lt IE 9]>
    <script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
    <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
    <![endif]-->
	<link rel="stylesheet" type="text/css" href="../static/styles.css" />
</head>
<body>
<div class="main-container">
    <section id="content">
        
        <div class="content-wrapper">
            <section id="guide" lang="zh_cn">
                <div class="container">
                    <div class="row">
                        <div class="col-xs-12 col-sm-8 col-md-8 guide-section">
                            <div style="color:gray; word-break: break-all; font-size:12px;">原文地址: <a href="https://www.elastic.co/guide/cn/elasticsearch/guide/current/function-score-filters.html" rel="nofollow">https://www.elastic.co/guide/cn/elasticsearch/guide/current/function-score-filters.html</a>, 版权归 www.elastic.co 所有<br/>
                            英文版地址: <a href="https://www.elastic.co/guide/en/elasticsearch/guide/current/function-score-filters.html" rel="nofollow">https://www.elastic.co/guide/en/elasticsearch/guide/current/function-score-filters.html</a>
                            </div>
                        <!-- start body -->
                  <div class="page_header">
<b>请注意:</b><br>本书基于 Elasticsearch 2.x 版本，有些内容可能已经过时。
</div>
<div id="content">
<div class="breadcrumbs">
<span class="breadcrumb-link"><a href="index.html">Elasticsearch: 权威指南</a></span>
»
<span class="breadcrumb-link"><a href="search-in-depth.html">深入搜索</a></span>
»
<span class="breadcrumb-link"><a href="controlling-relevance.html">控制相关度</a></span>
»
<span class="breadcrumb-node">过滤集提升权重</span>
</div>
<div class="navheader">
<span class="prev">
<a href="boosting-by-popularity.html">« 按受欢迎度提升权重</a>
</span>
<span class="next">
<a href="random-scoring.html">随机评分 »</a>
</span>
</div>
<div class="section">
<div class="titlepage"><div><div>
<h2 class="title">
<a id="function-score-filters"></a>过滤集提升权重<a class="edit_me edit_me_private" rel="nofollow" title="Editing on GitHub is available to Elastic" href="https://github.com/elasticsearch-cn/elasticsearch-definitive-guide/edit/cn/170_Relevance/50_Boosting_filtered_subsets.asciidoc">edit</a>
</h2>
</div></div></div>
<p>回到 <a class="xref" href="ignoring-tfidf.html" title="忽略 TF/IDF">忽略 TF/IDF</a> 里处理过的问题，我们希望根据每个度假屋的特性数量来评分，当时我们希望能用缓存的过滤器来影响评分，现在 <code class="literal">function_score</code> 查询正好可以完成这件事情。</p>
<p>到目前为止，我们展现的都是为所有文档应用单个函数的使用方式，现在会用过滤器将结果划分为多个子集（每个特性一个过滤器），并为每个子集使用不同的函数。</p>
<p>在下面例子中，我们会使用 <code class="literal">weight</code> 函数，它与 <code class="literal">boost</code> 参数类似可以用于任何查询。有一点区别是 <code class="literal">weight</code> 没有被 Luence 归一化成难以理解的浮点数，而是直接被应用。</p>
<p>查询的结构需要做相应变更以整合多个函数：</p>
<div class="pre_wrapper lang-json">
<pre class="programlisting prettyprint lang-json">GET /_search
{
  "query": {
    "function_score": {
      "filter": { <a id="CO117-1"></a><i class="conum" data-value="1"></i>
        "term": { "city": "Barcelona" }
      },
      "functions": [ <a id="CO117-2"></a><i class="conum" data-value="2"></i>
        {
          "filter": { "term": { "features": "wifi" }}, <a id="CO117-3"></a><i class="conum" data-value="3"></i>
          "weight": 1
        },
        {
          "filter": { "term": { "features": "garden" }}, <a id="CO117-4"></a><i class="conum" data-value="3"></i>
          "weight": 1
        },
        {
          "filter": { "term": { "features": "pool" }}, <a id="CO117-5"></a><i class="conum" data-value="3"></i>
          "weight": 2 <a id="CO117-6"></a><i class="conum" data-value="4"></i>
        }
      ],
      "score_mode": "sum", <a id="CO117-7"></a><i class="conum" data-value="5"></i>
    }
  }
}</pre>
</div>
<div class="calloutlist">
<table border="0" summary="Callout list">
<tr>
<td align="left" valign="top" width="5%">
<p><a href="#CO117-1"><i class="conum" data-value="1"></i></a></p>
</td>
<td align="left" valign="top">
<p><code class="literal">function_score</code> 查询有个 <code class="literal">filter</code> 过滤器而不是 <code class="literal">query</code> 查询。</p>
</td>
</tr>
<tr>
<td align="left" valign="top" width="5%">
<p><a href="#CO117-2"><i class="conum" data-value="2"></i></a></p>
</td>
<td align="left" valign="top">
<p><code class="literal">functions</code> 关键字存储着一个将被应用的函数列表。</p>
</td>
</tr>
<tr>
<td align="left" valign="top" width="5%">
<p><a href="#CO117-3"><i class="conum" data-value="3"></i></a><a href="#CO117-4"></a><a href="#CO117-5"></a></p>
</td>
<td align="left" valign="top">
<p>函数会被应用于和 <code class="literal">filter</code> 过滤器（可选的）匹配的文档。</p>
</td>
</tr>
<tr>
<td align="left" valign="top" width="5%">
<p><a href="#CO117-6"><i class="conum" data-value="4"></i></a></p>
</td>
<td align="left" valign="top">
<p><code class="literal">pool</code> 比其他特性更重要，所以它有更高 <code class="literal">weight</code> 。</p>
</td>
</tr>
<tr>
<td align="left" valign="top" width="5%">
<p><a href="#CO117-7"><i class="conum" data-value="5"></i></a></p>
</td>
<td align="left" valign="top">
<p><code class="literal">score_mode</code> 指定各个函数的值进行组合运算的方式。</p>
</td>
</tr>
</table>
</div>
<p>这个新特性需要注意的地方会在以下小节介绍。</p>
<div class="section">
<div class="titlepage"><div><div>
<h3 class="title">
<a id="_过滤_vs_查询"></a>过滤 vs. 查询<a class="edit_me edit_me_private" rel="nofollow" title="Editing on GitHub is available to Elastic" href="https://github.com/elasticsearch-cn/elasticsearch-definitive-guide/edit/cn/170_Relevance/50_Boosting_filtered_subsets.asciidoc">edit</a>
</h3>
</div></div></div>
<p>首先要注意的是 <code class="literal">filter</code> 过滤器代替了 <code class="literal">query</code> 查询，在本例中，我们无须使用全文搜索，只想找到 <code class="literal">city</code> 字段中包含 <code class="literal">Barcelona</code> 的所有文档，逻辑用过滤比用查询表达更清晰。过滤器返回的所有文档的评分 <code class="literal">_score</code> 的值为 <code class="literal">1</code> 。 <code class="literal">function_score</code> 查询接受 <code class="literal">query</code> 或 <code class="literal">filter</code> ，如果没有特别指定，则默认使用 <code class="literal">match_all</code> 查询。</p>
</div>

<div class="section">
<div class="titlepage"><div><div>
<h3 class="title">
<a id="_函数_functions"></a>函数 functions<a class="edit_me edit_me_private" rel="nofollow" title="Editing on GitHub is available to Elastic" href="https://github.com/elasticsearch-cn/elasticsearch-definitive-guide/edit/cn/170_Relevance/50_Boosting_filtered_subsets.asciidoc">edit</a>
</h3>
</div></div></div>
<p><code class="literal">functions</code> 关键字保持着一个将要被使用的函数列表。可以为列表里的每个函数都指定一个 <code class="literal">filter</code> 过滤器，在这种情况下，函数只会被应用到那些与过滤器匹配的文档，例子中，我们为与过滤器匹配的文档指定权重值 <code class="literal">weight</code> 为 <code class="literal">1</code> （为与 <code class="literal">pool</code> 匹配的文档指定权重值为 <code class="literal">2</code> ）。</p>
</div>

<div class="section">
<div class="titlepage"><div><div>
<h3 class="title">
<a id="_评分模式_score_mode"></a>评分模式 score_mode<a class="edit_me edit_me_private" rel="nofollow" title="Editing on GitHub is available to Elastic" href="https://github.com/elasticsearch-cn/elasticsearch-definitive-guide/edit/cn/170_Relevance/50_Boosting_filtered_subsets.asciidoc">edit</a>
</h3>
</div></div></div>
<p>每个函数返回一个结果，所以需要一种将多个结果缩减到单个值的方式，然后才能将其与原始评分 <code class="literal">_score</code> 合并。评分模式 <code class="literal">score_mode</code> 参数正好扮演这样的角色，它接受以下值：</p>
<div class="variablelist">
<dl class="variablelist">
<dt>
<span class="term">
<code class="literal">multiply</code>
</span>
</dt>
<dd>
函数结果求积（默认）。
</dd>
<dt>
<span class="term">
<code class="literal">sum</code>
</span>
</dt>
<dd>
函数结果求和。
</dd>
<dt>
<span class="term">
<code class="literal">avg</code>
</span>
</dt>
<dd>
函数结果的平均值。
</dd>
<dt>
<span class="term">
<code class="literal">max</code>
</span>
</dt>
<dd>
函数结果的最大值。
</dd>
<dt>
<span class="term">
<code class="literal">min</code>
</span>
</dt>
<dd>
函数结果的最小值。
</dd>
<dt>
<span class="term">
<code class="literal">first</code>
</span>
</dt>
<dd>
使用首个函数（可以有过滤器，也可能没有）的结果作为最终结果
</dd>
</dl>
</div>
<p>在本例中，我们将每个过滤器匹配结果的权重 <code class="literal">weight</code> 求和，并将其作为最终评分结果，所以会使用 <code class="literal">sum</code> 评分模式。</p>
<p>不与任何过滤器匹配的文档会保有其原始评分， <code class="literal">_score</code> 值的为 <code class="literal">1</code> 。</p>
</div>

</div>
<div class="navfooter">
<span class="prev">
<a href="boosting-by-popularity.html">« 按受欢迎度提升权重</a>
</span>
<span class="next">
<a href="random-scoring.html">随机评分 »</a>
</span>
</div>
</div>

                  <!-- end body -->
                        </div>
                        <div class="col-xs-12 col-sm-4 col-md-4" id="right_col">
                        
                        </div>
                    </div>
                </div>
            </section>
        </div>
    </section>
</div>
<script src="../static/cn.js"></script>
</body>
</html>